const express = require('express');
const XlsxPopulate = require('xlsx-populate');
const path = require('path');
const fs = require('fs');
const cors = require('cors'); // 引入 cors 中间件

const app = express();

// 使用 cors 中间件，允许所有来源的请求
app.use(cors());

// 解析 JSON 请求体
app.use(express.json());

// 检查 excelTemplates 目录是否存在，不存在则创建
const templateDir = path.join(__dirname, 'excelTemplates');
if (!fs.existsSync(templateDir)) {
    fs.mkdirSync(templateDir);
}

// 处理静态文件，使得前端页面可以被访问
app.use(express.static(__dirname));

// 处理文件处理请求
app.post('/excelprocess', async (req, res) => {
  try {
    // 获取 excelTemplates 目录下的所有文件
    const files = fs.readdirSync(templateDir);
    if (files.length === 0) {
      console.error('excelTemplates 目录中没有文件');
      return res.status(400).send('excelTemplates 目录中没有文件');
    }

    // 选择第一个文件作为模板
    const selectedFile = path.join(templateDir, files[0]);
    console.log('选定模板文件:', selectedFile);

    // 检查文件扩展名
    const fileExtension = path.extname(selectedFile).toLowerCase();
    if (fileExtension !== '.xlsx') {
      console.error('文件扩展名不正确:', fileExtension);
      return res.status(400).send('仅支持 .xlsx 文件');
    }

    // 检查文件是否可读
    fs.accessSync(selectedFile, fs.constants.R_OK);

    // 读取 Excel 文件
    const workbook = await XlsxPopulate.fromFileAsync(selectedFile);
    console.log('成功读取文件:', selectedFile);
    const sheet = workbook.sheet(0);

    // 获取传入的修改数据
    const modifications = req.body;

    // 根据传入的数据修改 Excel 文件内容
    for (const [cellAddress, value] of Object.entries(modifications)) {
      sheet.cell(cellAddress).value(value);
    }

    // 生成修改后的文件路径
    const defaultFileName = 'output.xlsx';
    const outputPath = path.join(__dirname, defaultFileName);

    // 将修改后的文件保存到磁盘
    await workbook.toFileAsync(outputPath);
    console.log('文件已保存到:', outputPath);

    // 对文件名进行严格编码
    const originalFileName = req.query.filename || '修改后.xlsx'; // 使用查询参数中的文件名或默认文件名
    const encodedFileName = encodeURIComponent(originalFileName).replace(/'/g, '%27');

    // 设置响应头并发送文件流
    res.setHeader('Content-Disposition', `attachment; filename="${encodedFileName}"`);
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

    // 使用流的方式发送文件
    const fileStream = fs.createReadStream(outputPath);
    fileStream.pipe(res);

    // 监听文件流的错误
    fileStream.on('error', (err) => {
      console.error('文件流发送时出错:', err);
      res.status(500).send('文件流发送时出错');
    });

    // 下载完成后删除临时文件
    // fileStream.on('end', () => {
    //   try {
    //     if (fs.existsSync(outputPath)) {
    //       fs.unlinkSync(outputPath);
    //     }
    //   } catch (unlinkErr) {
    //     console.error('删除临时文件时出错:', unlinkErr);
    //   }
    // });

  } catch (error) {
    console.error('处理文件时出错:', error.message);
    res.status(500).send(`处理文件时出错: ${error.message}`);
  }
});

// 启动服务器
const port = 3000;
app.listen(port, () => {
    console.log(`服务器运行在端口 http://localhost:${port}/`);
});




app.post('/excelprocess', async (req, res) => {
  try {
    const files = fs.readdirSync(templateDir);
    if (files.length === 0) {
      return res.status(400).send('excelTemplates 目录中没有文件');
    }

    const selectedFile = path.join(templateDir, files[0]);
    const fileExtension = path.extname(selectedFile).toLowerCase();
    if (fileExtension !== '.xlsx') {
      return res.status(400).send('仅支持 .xlsx 文件');
    }

    fs.accessSync(selectedFile, fs.constants.R_OK);
    const workbook = await XlsxPopulate.fromFileAsync(selectedFile);
    const modifications = req.body; // 前端传入的数组

    // 根据索引顺序处理工作表
    modifications.forEach((sheetData, sheetIndex) => {
      const sheetName = sheetData.sheetName;
      if (!sheetName) {
        console.warn(`警告：第 ${sheetIndex} 个工作表缺少 sheetName 字段，跳过修改`);
        return;
      }

      // 构造工作表名称
      const constructedSheetName = `${sheetName}${sheetIndex + 1}`;
      const sheet = workbook.sheet(constructedSheetName);

      if (!sheet) {
        console.warn(`警告：工作表 ${constructedSheetName} 不存在，跳过修改`);
        return;
      }

      // 确保数据字段存在
      const data = sheetData.data;
      if (!data) {
        console.warn(`警告：第 ${sheetIndex} 个工作表缺少 data 字段，跳过修改`);
        return;
      }

      // 应用单元格修改
      for (const [cellAddress, value] of Object.entries(data)) {
        try {
          sheet.cell(cellAddress).value(value);
        } catch (e) {
          console.error(`单元格 ${cellAddress} 修改失败：${e.message}`);
        }
      }
    });

    const outputPath = path.join(__dirname, 'output.xlsx');
    await workbook.toFileAsync(outputPath);

    const originalFileName = req.query.filename || '修改后.xlsx';
    const encodedFileName = encodeURIComponent(originalFileName).replace(/'/g, '%27');

    res.setHeader('Content-Disposition', `attachment; filename="${encodedFileName}"`);
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

    const fileStream = fs.createReadStream(outputPath);
    fileStream.pipe(res);

    fileStream.on('error', (err) => {
      console.error('文件流发送时出错:', err);
      res.status(500).send('文件流发送时出错');
    });

    fileStream.on('end', () => {
      try {
        if (fs.existsSync(outputPath)) {
          fs.unlinkSync(outputPath);
        }
      } catch (err) {
        console.error('删除临时文件时出错:', err);
      }
    });

  } catch (error) {
    console.error('处理文件时出错:', error.message);
    res.status(500).send(`处理文件时出错: ${error.message}`);
  }
});